#include "Application.h"

namespace App {
	// Helper to display a little (?) mark which shows a tooltip when hovered.
	static void HelpMarker(const char* desc)
	{
		ImGui::TextDisabled("(?)");
		if (ImGui::IsItemHovered())
		{
			ImGui::BeginTooltip();
			ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
			ImGui::TextUnformatted(desc);
			ImGui::PopTextWrapPos();
			ImGui::EndTooltip();
		}
	}

	void RenderUI(ParkingLot& pl) {
		// Docking Space-------------------------------------------------------------------------------------------
		static bool opt_fullscreen = true;
		static bool opt_padding = false;
		static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;

		// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
		// because it would be confusing to have two docking targets within each others.
		ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
		if (opt_fullscreen)
		{
			const ImGuiViewport* viewport = ImGui::GetMainViewport();
			ImGui::SetNextWindowPos(viewport->WorkPos);
			ImGui::SetNextWindowSize(viewport->WorkSize);
			ImGui::SetNextWindowViewport(viewport->ID);
			ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
			ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
			window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
			window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
		}
		else
		{
			dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
		}

		if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
			window_flags |= ImGuiWindowFlags_NoBackground;

		if (!opt_padding)
			ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
		ImGui::Begin("DockSpace Demo", nullptr, window_flags);
		if (!opt_padding)
			ImGui::PopStyleVar();

		if (opt_fullscreen)
			ImGui::PopStyleVar(2);

		// Submit the DockSpace
		ImGuiIO& io = ImGui::GetIO();
		if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
		{
			ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
			ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
		}

		if (ImGui::BeginMenuBar())
		{
			if (ImGui::BeginMenu("Doking"))
			{
				// Disabling fullscreen would allow the window to be moved to the front of other windows,
				// which we can't undo at the moment without finer window depth/z control.
				ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
				ImGui::MenuItem("Padding", NULL, &opt_padding);
				ImGui::Separator();

				if (ImGui::MenuItem("Flag: NoSplit", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoSplit; }
				if (ImGui::MenuItem("Flag: NoResize", "", (dockspace_flags & ImGuiDockNodeFlags_NoResize) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoResize; }
				if (ImGui::MenuItem("Flag: NoDockingInCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoDockingInCentralNode; }
				if (ImGui::MenuItem("Flag: AutoHideTabBar", "", (dockspace_flags & ImGuiDockNodeFlags_AutoHideTabBar) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_AutoHideTabBar; }
				if (ImGui::MenuItem("Flag: PassthruCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0, opt_fullscreen)) { dockspace_flags ^= ImGuiDockNodeFlags_PassthruCentralNode; }
				ImGui::Separator();
				ImGui::EndMenu();
			}
			ImGui::EndMenuBar();
		}

		ImGui::End();

		// Parking Lot Settings-------------------------------------------------------------------------------------
		if (!ImGui::Begin("Parking Lot Settings"))
		{
			ImGui::End();
			return;
		}

		if (ImGui::BeginTabBar("##TabBar"))
		{
			// Max Parking Space
			if (ImGui::BeginTabItem("Parking Space"))
			{

				static int max = 2;
				ImGui::Text("Set max parking space to: %d", max);
				ImGui::SliderInt("0 ~ 200", &max, 0, 200, "%d", ImGuiSliderFlags_AlwaysClamp);
				ImGui::SameLine(); HelpMarker("CTRL+click to input value.");

				// The logic of two buttons, a DFA
				static bool state1 = true;  // show "Please click ..."
				static bool state2 = false; // show "Saved!"
				static bool state3 = false; // show nothing
				if (ImGui::Button("Save")) {
					if (state1 == true);
					else if (state2 == true) {
						state1 = true;
						state2 = false;
					}
					else if (state3 == true) {
						state2 = true;
						state3 = false;
						pl.setMaxCarSpace(max);
					}
				}

				if (state1 == true) {
					ImGui::SameLine();
					ImGui::Text("Please click \"Clear\" first");
				}

				if (state2 == true) {
					ImGui::SameLine();
					ImGui::Text("Saved!");
				}

				if (ImGui::Button("Clear")) {
					state1 = false;
					state2 = false;
					state3 = true;
					pl = ParkingLot();
				}
				ImGui::EndTabItem();
			}

			// Charge
			if (ImGui::BeginTabItem("Charges"))
			{
				static int a = 10;
				static int b = 1;
				ImGui::Text("Set the charge standard to:", time);
				ImGui::InputInt("Charge in parking lot", &a);
				ImGui::InputInt("Charge in queue", &b);
				
				if (ImGui::Button("Save")) {
					pl.setParkPerHour(a);
					pl.setWaitPerHour(b);
				}

				ImGui::EndTabItem();
			}
			ImGui::EndTabBar();
		}
		ImGui::End();

		// View Port Settings-------------------------------------------------------------------------------------
		if (!ImGui::Begin("View Port Settings"))
		{
			ImGui::End();
			return;
		}
		static float sz = 45.0f;
		static float thickness = 3.0f;
		static ImVec4 colf = ImVec4(0.0f, 1.0f, 0.0f, 1.0f);
		const ImU32 col = ImColor(colf);
		ImGui::DragFloat("Size", &sz, 0.2f, 30.0f, 100.0f, "%.0f");
		ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 10.0f, "%.02f");
		ImGui::ColorEdit4("Color", &colf.x);

		ImGui::End();

		// Operations-----------------------------------------------------------------------------------------------
		if (!ImGui::Begin("Opertaion"))
		{
			ImGui::End();
			return;
		}

		if (ImGui::BeginTabBar("##TabBar"))
		{
			// Arrive
			if (ImGui::BeginTabItem("Arrive"))
			{
				static char str[128] = "";
				ImGui::Text("Plate number: %s", str);
				ImGui::InputTextWithHint("Plate number", "Enter plate number here", str, IM_ARRAYSIZE(str));
				
				static float size = 1;
				ImGui::Text("Car size: %.1f", size);
				ImGui::InputFloat("input float", &size, 0.5f, 5.0f, "%.1f");

				static int time = 0;
				ImGui::Text("Arrive time: %d", time);
				ImGui::InputInt("Arrive time", &time);

				if (ImGui::Button("Commit")) {
					ParkingInfo temp_pi;
					strcpy_s(temp_pi.plateNumber, str);
					temp_pi.carSize = size;
					temp_pi.time = time;

					pl.arrive(temp_pi);
					
					strcpy_s(str, "");
					size = 1;
					time = 0;
					ImGui::OpenPopup("Arrive Information");
				}

				// Always center this window when appearing
				ImVec2 center = ImGui::GetMainViewport()->GetCenter();
				ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));

				if (ImGui::BeginPopupModal("Arrive Information", NULL, ImGuiWindowFlags_AlwaysAutoResize))
				{
					ImGui::Text(pl.getPopInfo());
					ImGui::Separator();
					if (ImGui::Button("OK", ImVec2(300, 0))) { ImGui::CloseCurrentPopup(); }
					ImGui::SetItemDefaultFocus();
					ImGui::EndPopup();
				}

				ImGui::EndTabItem();
			}

			// Depart
			if (ImGui::BeginTabItem("Depart"))
			{
				static char str[128] = "";
				ImGui::Text("Plate number: %s", str);
				ImGui::InputTextWithHint("Plate number", "Enter plate number here", str, IM_ARRAYSIZE(str));
				ImGui::EndTabItem();

				static int time = 0;
				ImGui::Text("Depart time: %d", time);
				ImGui::InputInt("Depart time", &time);
				if (ImGui::Button("Commit")) {
					ParkingInfo temp_pi;
					strcpy_s(temp_pi.plateNumber, str);
					temp_pi.time = time;

					pl.depart(temp_pi);

					strcpy_s(str, "");
					time = 0;

					ImGui::OpenPopup("Depart Information");
				}

				// Always center this window when appearing
				ImVec2 center = ImGui::GetMainViewport()->GetCenter();
				ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));

				if (ImGui::BeginPopupModal("Depart Information", NULL, ImGuiWindowFlags_AlwaysAutoResize))
				{
					ImGui::Text(pl.getPopInfo());
					ImGui::Separator();
					if (ImGui::Button("OK", ImVec2(300, 0))) { ImGui::CloseCurrentPopup(); }
					ImGui::SetItemDefaultFocus();
					ImGui::EndPopup();
				}
			}

			ImGui::EndTabBar();
		}

		ImGui::End();

		// View Port------------------------------------------------------------------------------------------------
		if (!ImGui::Begin("View Port"))
		{
			ImGui::End();
			return;
		}

		ImGui::PushItemWidth(-ImGui::GetFontSize() * 15);
		ImDrawList* draw_list = ImGui::GetWindowDrawList();

		const ImVec2 p = ImGui::GetCursorScreenPos();
		const float spacing = 10.0f;

		float x = p.x + 4.0f;
		float y = p.y + 4.0f;

		
		std::string str1 = "Max parking space:" + std::to_string(pl.getMaxCarSpace());
		draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), str1.c_str());
		y += 40.0f;

		std::string str2 = "Charge in parking lot: $" + std::to_string(pl.getParkPerHour()) + "/h";
		draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), str2.c_str());
		y += 40.0f;

		std::string str3 = "Charge in waiting queue: $" + std::to_string(pl.getWaitPerHour()) + "/h";
		draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), str3.c_str());
		y += 40.0f;

		draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), "STACK:");
		y += 40.0f;

		if (!pl.getStackSize()) {
			draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), "Empty now...");
			y += 40.0f;
		}

		for (int n = 0; n < pl.getStackSize(); n++)
		{
			draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + 2 * sz), col, 0.0f, ImDrawFlags_None, thickness);// Draw a rectangle car
			x += 5;
			y += 5;
			int y_info = y;
			draw_list->AddText(ImVec2(x, y_info), ImColor(255, 255, 255, 255), pl.getPlateInStack(n));
			y_info += 20;
			draw_list->AddText(ImVec2(x, y_info), ImColor(255, 255, 255, 255), std::to_string(pl.getSizeInStack(n)).c_str());
			y_info += 20;
			draw_list->AddText(ImVec2(x, y_info), ImColor(255, 255, 255, 255), std::to_string(pl.getTimeInStack(n)).c_str());
			

			x = p.x + 4;
			y += 2 * (sz + spacing);
		}

		ImGui::Dummy(ImVec2((sz + spacing) * 10.2f, (2 * sz + 2 * spacing) * 3.0f));


		draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), "QUEUE:");

		y += 40.0f;
		float y1 = y;

		if (!pl.getQueueSize()) {
			draw_list->AddText(ImVec2(x, y), ImColor(255, 255, 255, 255), "Empty now...");
		}

		for (int n = 0; n < pl.getQueueSize(); n++)
		{
			draw_list->AddRect(ImVec2(x, y), ImVec2(x + 2 * sz, y + sz), col, 0.0f, ImDrawFlags_None, thickness); // Draw a rectangle car
			x += 5;
			y += 2;
			int y_info = y;
			int x_info = x;
			draw_list->AddText(ImVec2(x, y_info), ImColor(255, 255, 255, 255), pl.getPlateInQueue(n));
			y_info += 20;
			draw_list->AddText(ImVec2(x, y_info), ImColor(255, 255, 255, 255), std::to_string(pl.getSizeInQueue(n)).c_str());
			x_info += 40;
			draw_list->AddText(ImVec2(x_info, y_info), ImColor(255, 255, 255, 255), std::to_string(pl.getTimeInQueue(n)).c_str());

			y = y1;
			x += 2 * (sz + spacing);
		}
		ImGui::PopItemWidth();
		ImGui::End();
	}
}